using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Media3D;
using System.Windows;
using System.Collections;

namespace _3DHouse.CustomControl
{
    /// <summary>
    /// 变换控制方向指针，
    /// </summary>
   public class Direction:ModelVisual3D
    {
       public Direction()
       {
           Children.Add(new DirectionX());
           Children.Add(new DirectionY());
           Children.Add(new DirectionZ());
       }
       /// <summary>
       /// 变换属性的依赖项属性
       /// </summary>
       public static readonly new DependencyProperty TransformProperty = DependencyProperty.Register("Transform", typeof(Transform3D), typeof(Direction),
           new FrameworkPropertyMetadata(new PropertyChangedCallback(OnTransformChange)));
       /// <summary>
       ///  获取或设置在3D模型上设置的转换
       /// </summary>       
       public new Transform3D Transform
       {
           get
           {
               return GetValue(TransformProperty) as Transform3D;
           }
           set
           {
               SetValue(TransformProperty, value);
           }
       }
       /// <summary>
       /// 变换属性更改触发的事件，更改模型的坐标
       /// </summary>
       static void OnTransformChange(DependencyObject sender, DependencyPropertyChangedEventArgs e)
       {

           Direction cube = sender as Direction;

           if (cube.Children.Count>0)
           {
               foreach (ModelVisual3D model in cube.Children)
               {
                   model.Transform = cube.Transform.Clone();
                   cube.SetTransform(model);
                   //还原变换值以便于触发change事件
                   cube.ClearTransform(model.Transform);
               }
           }
           //判断children
           //children里面是Modelvisual还是Viewport2DVisual3D
       }
       /// <summary>
       /// 设置模型坐标变换
       /// </summary>
       /// <param name="cube">模型对象</param>
       protected void SetTransform(ModelVisual3D cube)
       {
            if (cube.Content != null && cube.Content is GeometryModel3D)//单个Mode
           {
               GeometryModel3D geome = cube.Content as GeometryModel3D;
               MeshGeometry3D mesh = geome.Geometry as MeshGeometry3D;
               ArrayList arrX = new ArrayList();
               ArrayList arrY = new ArrayList();
               ArrayList arrZ = new ArrayList();
               //把各轴坐标做成数组
               for (int n = 0; n < mesh.Positions.Count; n++)
               {
                   arrX.Add(mesh.Positions[n].X);
                   arrY.Add(mesh.Positions[n].Y);
                   arrZ.Add(mesh.Positions[n].Z);
               }
               JudgeTransform(mesh, cube.Transform, arrX, arrY, arrZ);        
           }
       }
       /// <summary>
       /// 判断变换是单个还是多个
       /// </summary>
       /// <param name="mesh">要更改的3D基本图形</param>
       /// <param name="transform">模型的变换</param>
       /// <param name="arrX">X轴分量集合</param>
       /// <param name="arrY">Y轴分量集合</param>
       /// <param name="arrZ">Z轴分量集合</param>
       void JudgeTransform(MeshGeometry3D mesh, Transform3D transform, ArrayList arrX, ArrayList arrY, ArrayList arrZ)
       {
           //判断是否是变化组合
           if (transform is Transform3DGroup)
           {//判断三种变换
               Transform3DGroup tfg = transform as Transform3DGroup;
               foreach (Transform3D trans in tfg.Children)
               {
                   TransformInfo(mesh, trans, arrX, arrY, arrZ);
               }
           }
           else
           {
               TransformInfo(mesh, transform, arrX, arrY, arrZ);
           }
       }
       /// <summary>
       /// 三种坐标变换
       /// </summary>
       /// <param name="mesh">要更改的3D基本图形</param>
       /// <param name="transform">模型的变换</param>
       /// <param name="arrX">X轴分量集合</param>
       /// <param name="arrY">Y轴分量集合</param>
       /// <param name="arrZ">Z轴分量集合</param>
       void TransformInfo(MeshGeometry3D mesh, Transform3D transform, ArrayList arrX, ArrayList arrY, ArrayList arrZ)
       { //获得模型的边界值
           double maxX = (double)arrX[arrX.Count - 1];//最大X值
           double minX = (double)arrX[0];//最小X值
           double maxZ = (double)arrZ[arrZ.Count - 1];//最大Z值
           double minZ = (double)arrZ[0];//最小Z值
           double minY = (double)arrY[0];         //最小Y值 `
           //平移变换
           if (transform is TranslateTransform3D)
           {              
                   TranslateTransform3D trans = transform as TranslateTransform3D;
                   Point3DCollection point3ds = TransformCoordinate(mesh, trans);
                   mesh.Positions = point3ds;  //更改3D基本图形的坐标              
           }
           
       }    
       /// <summary>
       /// 平移变换坐标
       /// </summary>
       /// <param name="mesh">MeshGeometry3D对象</param>
       /// <param name="trans">平移变换，保存平移的值</param>
       /// <returns></returns>
       private Point3DCollection TransformCoordinate(MeshGeometry3D mesh, TranslateTransform3D trans)
       {
           Point3DCollection point3ds = new Point3DCollection();
           for (int n = 0; n < mesh.Positions.Count; n++)//遍历每个点
           {
               Point3D point = mesh.Positions[n];
               point.X += trans.OffsetX;
               point.Y += trans.OffsetY;
               point.Z += trans.OffsetZ;
               point3ds.Add(point);
           }
           return point3ds;
       }
       #region 还原变换值以便于触发change事件
       void ClearTransform(Transform3D transform)
       {
           //判断是否是变化组合
           if (transform is Transform3DGroup)
           {//判断三种变换
               Transform3DGroup tfg = transform as Transform3DGroup;
               foreach (Transform3D trans in tfg.Children)
               {
                   ClearTransformInfo(trans);
               }
           }
           else
           {
               ClearTransformInfo(transform);
           }
       }
       void ClearTransformInfo(Transform3D transform)
       {
           if (transform is TranslateTransform3D)
           {
               TranslateTransform3D trans = transform as TranslateTransform3D;
               trans.OffsetX = 0;
               trans.OffsetY = 0;
               trans.OffsetZ = 0;
           }
           else if (transform is RotateTransform3D)
           {
               RotateTransform3D trans = transform as RotateTransform3D;
               AxisAngleRotation3D axi = trans.Rotation as AxisAngleRotation3D;
               axi.Angle = 0;//角度

           }
           else if (transform is ScaleTransform3D)
           {
               ScaleTransform3D trans = transform as ScaleTransform3D;
               trans.ScaleX = 1;
               trans.ScaleY = 1;
               trans.ScaleZ = 1;
           }
       }
       #endregion
    }
    /// <summary>
    /// X方向指针
    /// </summary>
   public class DirectionX : ModelVisual3D
   {
       public DirectionX()
       {
           Content = Cube.TransformResources((GeometryModel3D)Application.Current.Resources["x"]);
           Transform = new TranslateTransform3D();
       }
      
   }
   /// <summary>
   /// Y方向指针
   /// </summary>
   public class DirectionY : ModelVisual3D
   {
       public DirectionY()
       {
           Content = Cube.TransformResources((GeometryModel3D)Application.Current.Resources["y"]);
           Transform = new TranslateTransform3D();
       }
   }
   /// <summary>
   /// Z方向指针
   /// </summary>
   public class DirectionZ : ModelVisual3D
   {
       public DirectionZ()
       {
           Content = Cube.TransformResources((GeometryModel3D)Application.Current.Resources["z"]);
           Transform = new TranslateTransform3D();
       }
   }
}
